﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using VIP.Extension;

namespace VIP.Pool {
    /// <summary>
    /// 子弹类
    /// </summary>
    [Serializable]
    class BulletClass
    {
        public float TaskTime;
        public GameObject Bullet;
    }

    /// <summary>
    /// 子弹池
    /// </summary>
    public class BulletPool : MonoBehaviour
    {

        /// <summary>
        /// 子弹
        /// </summary>
        [SerializeField]
        private GameObject bulletObj;

        /// <summary>
        /// 子弹池初始大小
        /// </summary>
        [SerializeField]
        private int poolSize = 5;

        /// <summary>
        /// 回收子弹间隔时间
        /// </summary>
        [SerializeField]
        private float autoRecoveryTime = 5;

        /// <summary>
        /// 是否开启自动回收子弹
        /// </summary>
        [SerializeField]
        private bool autoRecovery;

        /// <summary>
        /// 是否锁定子弹池大小
        /// </summary>
        [SerializeField]
        private bool lockPoolSize = false;

        /// <summary>
        /// 子弹池
        /// </summary>
        //[SerializeField]
        private List<GameObject> bulletList = new List<GameObject>();

        /// <summary>
        /// 当前指向列表位置索引
        /// </summary>
        private int currentIndex = 0;

        /// <summary>
        /// 缓存自动销毁列表
        /// </summary>
        //[SerializeField] //这个是用来查看缓存列表
        private List<BulletClass> bcList = new List<BulletClass>();

        private void Start()
        {
            //初始化列表
            bulletList = new List<GameObject>();
            for (int i = 0; i < poolSize; i++)
            {
                //创建子弹对象
                GameObject obj = Instantiate(bulletObj);
                //设置子弹无效
                obj.SetActive(false);
                //把子弹添加到列表（对象池）中
                bulletList.Add(obj);
            }
        }

        private void Update()
        {
            //如果开启了自动回收
            if (autoRecovery)
            {
                for (int i = 0; i < bcList.Count; i++)
                {
                    BulletClass bc = bcList[i];
                    if ((bc.TaskTime -= Time.deltaTime) <= 0)
                    {
                        bc.Bullet.Disable();
                        bcList.RemoveAt(i);
                        i--;
                    }
                }
            }
        }

        /// <summary>
        /// 获取对象池中可以使用的子弹
        /// </summary>
        /// <returns></returns>
        public GameObject GetBullet()
        {
            //把对象池遍历一遍
            for (int i = 0; i < bulletList.Count; i++)
            {
                //这里简单优化了一下，每一次遍历都是从上一次被使用的子弹的下一个，而不是每次遍历从0开始。
                //例如上一次获取了第4个子弹，currentIndex就为5，这里从索引5开始遍历，这是一种贪心算法。
                int index = (currentIndex + i) % bulletList.Count;
                //判断该子弹是否在场景中激活。
                if (!bulletList[index].activeInHierarchy)
                {
                    currentIndex = (index + 1) % bulletList.Count;
                    //找到没有被激活的子弹
                    GameObject disableBullet = bulletList[index];
                    //如果开启自动回收子弹
                    if (autoRecovery)
                    {
                        BulletClass bc = new BulletClass();
                        bc.TaskTime = autoRecoveryTime;
                        bc.Bullet = disableBullet;
                        bcList.Add(bc);
                    }
                    return disableBullet;
                }
            }
            //如果遍历完一遍子弹库发现没有可以用的，执行下面
            //如果没有锁定对象池大小，创建子弹并添加到对象池中。
            if (!lockPoolSize)
            {
                GameObject obj = Instantiate(bulletObj);
                bulletList.Add(obj);
                return obj;
            }
            //如果遍历完没有而且锁定了对象池大小，返回空。
            return null;
        }

    }

}
